use tracing::debug;

use crate::ast_define::{declear::*, general::*, statement::*};
use crate::semantic_analysis::{SemanticError, Type};

impl super::TypeChecker {
    /// 检查常量表达式
    pub fn check_const_exp(&mut self, const_exp: &ConstExp) {
        self.check_add_exp(&const_exp.add_exp);
    }

    /// 检查变量定义
    pub fn check_var_def(&mut self, var_def: &VarDef) {
        match var_def {
            VarDef::Ident_ConstExp_Brackets_Wrapper_Assign_InitVal(def) => {
                // 检查数组维度表达式
                for const_exp in &def.const_exp {
                    self.check_const_exp(const_exp);
                }
                // 检查初始值
                self.check_init_val(&def.init_val);
            }
            VarDef::Ident_ConstExp_Brackets_Wrapper(def) => {
                // 检查数组维度表达式
                for const_exp in &def.const_exp {
                    self.check_const_exp(const_exp);
                }
            }
        }
    }

    /// 检查初始值
    pub fn check_init_val(&mut self, init_val: &InitVal) {
        // ! 不存在需要检查数组赋值的地方
        if let InitVal::Exp(exp) = init_val {
            self.check_exp(exp);
        }
    }

    /// 检查赋值语句
    pub fn check_assign_stmt(&mut self, assign_stmt: &LVal_Assign_Exp_Stmt) {
        // 检查左值
        let lval_type = self.check_lval(&assign_stmt.l_val, true); // true表示这是赋值的左侧

        // 检查右值
        let rval_type = self.check_exp(&assign_stmt.exp);

        debug!(
            "\n左值字面量是: {:#?}\n类型: {:#?}",
            assign_stmt.l_val, lval_type
        );
        debug!(
            "\n右值字面量是: {:#?}\n类型: {:#?}",
            assign_stmt.exp, rval_type
        );
        // 如果右值类型是函数, 则报错(变量未定义)
        if let Some(rval_type) = &rval_type
            && rval_type.is_function()
        {
            self.errors.push(SemanticError::undefined_variable(
                "",
                assign_stmt.meta_info.clone(),
            ));
            return;
        }

        // 检查类型匹配
        if let (Some(lval_type), Some(rval_type)) = (lval_type, rval_type)
            && !lval_type.is_assignable_from(&rval_type)
        {
            self.errors
                .push(SemanticError::type_mismatched_for_assignment(
                    assign_stmt.meta_info.clone(),
                ));
        }
    }

    /// 检查左值表达式
    pub fn check_lval(&mut self, lval: &LVal, is_assignment_target: bool) -> Option<Type> {
        // 查找变量
        debug!("\n即将检查左值表达式: {:#?}", lval);
        let symbol = match self.symbol_table.lookup(&lval.ident.value) {
            Some(symbol) => symbol,
            None => {
                self.errors.push(SemanticError::undefined_variable(
                    &lval.ident.value,
                    lval.ident.meta_info.clone(),
                ));
                return None;
            }
        };

        // 检查是否为函数（函数不能被赋值）
        if is_assignment_target && symbol.symbol_type.is_function() {
            self.errors
                .push(SemanticError::invalid_left_hand_side_of_assignment(
                    lval.meta_info.clone(),
                ));
            return None;
        }

        let mut current_type = symbol.symbol_type.get_type().clone();

        // 处理数组下标
        for exp in &lval.exps {
            match &current_type {
                Type::Array(_) => {
                    // 检查下标表达式
                    let index_type = self.check_exp(exp);
                    if let Some(index_type) = index_type
                        && index_type != Type::Int
                    {
                        self.errors
                            .push(SemanticError::type_mismatched_for_operands(
                                exp.meta_info.clone(),
                            ));
                        return None;
                    }
                    // // 获取数组元素类型
                    // if let Some(element_type) = current_type.array_element_type() {
                    //     current_type = element_type;
                    // } else {
                    //     // 这种情况不应该发生
                    //     return None;
                    // }
                }
                _ => {
                    // 对非数组使用下标运算符
                    self.errors.push(SemanticError::not_an_array(
                        &lval.ident.value,
                        lval.ident.meta_info.clone(),
                    ));
                    return None;
                }
            }
        }

        // 对于数组类型, 每有一个取括号操作, 返回的类型就减少一维, 直到减少到int类型
        if let Type::Array(type_dims) = current_type {
            let dims_of_ident = type_dims as i32 - lval.exps.len() as i32;
            debug!("\ndims_of_ident: {}", dims_of_ident);
            match dims_of_ident {
                1.. => current_type = Type::Array(dims_of_ident as usize),
                0 => current_type = Type::Int,
                _ => {
                    self.errors.push(SemanticError::not_an_array(
                        &lval.ident.value,
                        lval.ident.meta_info.clone(),
                    ));
                    return None;
                }
            }
        }
        debug!("\n最终返回的类型: {:#?}", current_type);
        Some(current_type)
    }
}
